]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
telepathyClient: send typing notifications
authorJonny Lamb <jonnylamb@gnome.org>
Thu, 7 Jul 2011 12:42:07 +0000 (13:42 +0100)
committerAlban Crequy <alban.crequy@collabora.co.uk>
Thu, 7 Jul 2011 15:31:22 +0000 (16:31 +0100)
If we're typing we want to send composing. If we empty the entry we
want to send active. If we're typing but don't type any more for
COMPOSING_STOP_TIMEOUT seconds, we want to send paused. Simple.

This behaviour was stolen from Empathy where it has won many awards.

https://bugzilla.gnome.org/show_bug.cgi?id=650196

Based on patch from Jonny Lamb <jonnylamb@gnome.org>
Signed-off-by: Alban Crequy <alban.crequy@collabora.co.uk>
js/ui/telepathyClient.js

index b916fac6f14ba5ba43b1e578daea38ac278a1cae..e0bd8d0636ce0e039f70781e715284c2d8434fba 100644 (file)
@@ -24,6 +24,9 @@ const SCROLLBACK_IDLE_LENGTH = 5;
 // See Source._displayPendingMessages
 const SCROLLBACK_HISTORY_LINES = 10;
 
+// See Notification._onEntryChanged
+const COMPOSING_STOP_TIMEOUT = 5;
+
 const NotificationDirection = {
     SENT: 'chat-sent',
     RECEIVED: 'chat-received'
@@ -71,6 +74,7 @@ Client.prototype = {
     _init : function() {
         // channel path -> ChatSource
         this._chatSources = {};
+        this._chatState = Tp.ChannelChatState.ACTIVE;
 
         // Set up a SimpleObserver, which will call _observeChannels whenever a
         // channel matching its filters is detected.
@@ -458,6 +462,19 @@ ChatSource.prototype = {
         }));
     },
 
+    setChatState: function(state) {
+        // We don't want to send COMPOSING every time a letter is typed into
+        // the entry. We send the state only when it changes. Telepathy/Empathy
+        // might change it behind our back if the user is using both
+        // gnome-shell's entry and the Empathy conversation window. We could
+        // keep track of it with the ChatStateChanged signal but it is good
+        // enough right now.
+        if (state != this._chatState) {
+          this._chatState = state;
+          this._channel.set_chat_state_async(state, null);
+        }
+    },
+
     _presenceChanged: function (contact, presence, status, message) {
         let msg, shouldNotify, title;
 
@@ -547,6 +564,7 @@ ChatNotification.prototype = {
         this._responseEntry = new St.Entry({ style_class: 'chat-response',
                                              can_focus: true });
         this._responseEntry.clutter_text.connect('activate', Lang.bind(this, this._onEntryActivated));
+        this._responseEntry.clutter_text.connect('text-changed', Lang.bind(this, this._onEntryChanged));
         this.setActionArea(this._responseEntry);
 
         this._oldMaxScrollAdjustment = 0;
@@ -563,6 +581,7 @@ ChatNotification.prototype = {
 
         this._history = [];
         this._timestampTimeoutId = 0;
+        this._composingTimeoutId = 0;
     },
 
     /**
@@ -735,6 +754,39 @@ ChatNotification.prototype = {
         // see Source._messageSent
         this._responseEntry.set_text('');
         this.source.respond(text);
+    },
+
+    _composingStopTimeout: function() {
+        this._composingTimeoutId = 0;
+
+        this.source.setChatState(Tp.ChannelChatState.PAUSED);
+
+        return false;
+    },
+
+    _onEntryChanged: function() {
+        let text = this._responseEntry.get_text();
+
+        // If we're typing, we want to send COMPOSING.
+        // If we empty the entry, we want to send ACTIVE.
+        // If we've stopped typing for COMPOSING_STOP_TIMEOUT
+        //    seconds, we want to send PAUSED.
+
+        // Remove composing timeout.
+        if (this._composingTimeoutId > 0) {
+            Mainloop.source_remove(this._composingTimeoutId);
+            this._composingTimeoutId = 0;
+        }
+
+        if (text != '') {
+            this.source.setChatState(Tp.ChannelChatState.COMPOSING);
+
+            this._composingTimeoutId = Mainloop.timeout_add_seconds(
+                COMPOSING_STOP_TIMEOUT,
+                Lang.bind(this, this._composingStopTimeout));
+        } else {
+            this.source.setChatState(Tp.ChannelChatState.ACTIVE);
+        }
     }
 };